﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;
using LGE;

namespace GGJ2014
{
    public class Player : GameObject
    {
        public Vector2 CameraOffset { get { return drawPosition - position; } }

        bool isWalking = false;
        public Vector2 dir = Direction.Down;

        public List<Texture2D> avatars = new List<Texture2D>();
        public SpriteSheetState[] state = new SpriteSheetState[5];
        public float moveSpeed = 7;
        public Cue walkCue;

        public Class c = Class.Archer;
        public int[] classMoveSpeed = new int[] { 4, 3, 5, 2, 6 };
        
        int witchSpeedBooster = 4;
        public double actionTimer = 0;
        double cdTimer = 0;
        int cdDuration = 1000;
        int actionDuration = 1000;

        ActionObject aObj = null;

        public Player(PlayScreen ps)
            : base(ps, GameObject.tile)
        {
            HitBox = new Rectangle(0, 20, 64, 74);
            drawPosition = new Vector2(1280 / 2, 720 / 2);
            #region Load Spritesheets
            for (int i = 0; i < 5; ++i)
            {
                avatars.Add(Engine.Load<Texture2D>("Images\\Character\\Avatar\\" + i));
                state[i] = new SpriteSheetState(this);
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_standF_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_standB_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_standS_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_standS_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_walkF_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_walkB_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_walkS_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
                state[i].Add(Engine.Load<Texture2D>("Images\\Character\\" + i + "\\ninja_walkS_96x96-120ms"), new SpriteSheet(this, 96, 96, 120, true));
            }
            #endregion
            state[(int)c].Change(States.StandU);
            state[(int)c].Change(States.StandD);

            walkCue = Audio.GetCue("char_walk");
            walkCue.Play();
        }

        public override void Update(GameTime gameTime)
        {
            speed = new Vector2(0, 0);
            moveSpeed = classMoveSpeed[(int)c];

            #region Timers
            if (cdTimer > 0)
            {
                cdTimer -= gameTime.ElapsedGameTime.TotalMilliseconds;
            }
            else
            {
                cdTimer = 0;
                if (actionTimer > 0)
                {
                    if (c == Class.Witch) moveSpeed += witchSpeedBooster;
                    actionTimer -= gameTime.ElapsedGameTime.TotalMilliseconds;
                    if (actionTimer < 0)
                    {
                        actionTimer = 0;
                        cdTimer = cdDuration;
                    }
                }
            }
            #endregion

            UpdateInput(gameTime);
            if (aObj != null)
            {
                aObj.Update(gameTime);
                if (actionTimer <= 0) aObj = null;
            }
            //if (CheckCollisionWithDeath()) Die();
            MoveAndCheckCollisionWithMap(MapManager.CollisionLayer);

            //if (HitBox.Intersects(ps.ExitRect)) { walkCue.Dispose(); Audio.DisposeAll(); GameScreenManager.ChangeScreen(new Scene2(ps.map)); }

            state[(int)c].Update(gameTime);
        }

        public bool CheckCollisionWithDeath()
        {
            bool collided = false;

            position.Y += 1f;
            collided = (MapManager.CollisionH(this, ps.map, MapManager.DeathLayer, speed.X < 0) != 0) ||
                       (MapManager.CollisionV(this, ps.map, MapManager.DeathLayer, speed.Y < 0) != 0);
            position.Y -= 1f;

            return collided;
        }

        private void UpdateInput(GameTime gameTime)
        {
            if (!alive)
            {
                //GameScreenManager.ChangeScreen(new StartScreen());
                return;
            }

            if (Input.Down(KeyMap.Action) && actionTimer == 0 && cdTimer == 0)
            {
                actionTimer = actionDuration;
                switch (c)
                {
                    case Class.Archer: aObj = new ArcherArrow(ps);break;
                    case Class.Fairy: aObj = new FairyShield(ps); break;
                    case Class.Ninja: aObj = new NinjaSword(ps);break;
                    case Class.Warrior: aObj = new WarriorHammer(ps);break;
                }
            }

            if (Input.Pressed(KeyMap.ScrollLeft)) { c--; if ((int)c < 0) c = Class.Witch; }
            if (Input.Pressed(KeyMap.ScrollRight)) { c++; if ((int)c > 4) c = Class.Archer; }

            #region Movement
            if (Input.Down(KeyMap.Left))
            {
                speed.X = -moveSpeed;
                isWalking = true;
                dir = Direction.Left;
            }
            else if (Input.Down(KeyMap.Right))
            {
                speed.X = moveSpeed;
                isWalking = true;
                dir = Direction.Right;
            }
            else if (Input.Down(KeyMap.Up))
            {
                speed.Y = -moveSpeed;
                isWalking = true;
                dir = Direction.Up;
            }
            else if (Input.Down(KeyMap.Down))
            {
                speed.Y = moveSpeed;
                isWalking = true;
                dir = Direction.Down;
            }
            else isWalking = false;
            #endregion

            // SFX char_walk
            if (speed.Length() > 0)
                walkCue.Resume();
            else
                walkCue.Pause();

            state[(int)c].Change((isWalking ? 4 : 0) + (dir == Direction.Down ? 0 : dir == Direction.Up ? 1 : dir == Direction.Right ? 2 : 3));
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(sprite, drawPosition + new Vector2(0, 0), sourceRectangle, Color.White, rotation, origin, scale,
                state[(int)c].actualState == States.StandL || state[(int)c].actualState == States.WalkL ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0);

            if (aObj != null) aObj.Draw(spriteBatch);

            //if (YOGO.isDebugMode) DrawCollidingTiles(spriteBatch);
            if (GGJ2014.isDebugMode) DrawHitBox(spriteBatch);
        }

        public void Die()
        {
            if (!alive) return;
            walkCue.Dispose();
            Audio.bgmCue.Pause();
            //Audio.PlayCue("char_die");
            alive = false;
        }

        public enum Class : int { Archer = 0, Fairy = 1, Ninja = 2, Warrior = 3, Witch = 4 };

        public static class States  
        {
            public const int StandD = 0;
            public const int StandU = 1;
            public const int StandR = 2;
            public const int StandL = 3;
            public const int WalkD = 4;
            public const int WalkU = 5;
            public const int WalkR = 6;
            public const int WalkL = 7;
        }
    }
}
